Table Per Concrete Class (TPC) মডেল হল একটি ORM কৌশল যেখানে প্রতি কনক্রিট ক্লাসের জন্য আলাদা টেবিল তৈরি করা হয়। এতে, প্রতিটি কনক্রিট ক্লাস তার নিজস্ব টেবিল ধারণ করে এবং এতে সমস্ত প্রপার্টি সংরক্ষিত থাকে, যার মধ্যে সত্ত্বেও পূর্ববর্তী ক্লাসের উত্তরাধিকারসূত্রে প্রাপ্ত প্রপার্টিগুলি অন্তর্ভুক্ত থাকে না। এই কৌশলটি Inheritance Mapping এর একটি অংশ এবং যখন আপনি টেবিলগুলোকে সহজ ও স্বতন্ত্র রাখতে চান তখন এটি ব্যবহার করা হয়।
এখানে, Table Per Concrete Class কৌশলটি ব্যবহার করার জন্য NHibernate এর মাধ্যমে একটি উদাহরণ দেওয়া হলো।
1. Inheritance Structure
ধরা যাক, আপনি দুটি কনক্রিট ক্লাস তৈরি করেছেন: Employee এবং Manager। Manager ক্লাসটি Employee ক্লাস থেকে উত্তরাধিকারী, তবে এই দুটি ক্লাসের জন্য আলাদা আলাদা টেবিল থাকবে।
ক্লাস মডেল:
public class Employee
{
public virtual int Id { get; set; }
public virtual string Name { get; set; }
public virtual decimal Salary { get; set; }
}
public class Manager : Employee
{
public virtual string Department { get; set; }
}
এখানে, Manager ক্লাসটি Employee ক্লাস থেকে উত্তরাধিকারসূত্রে প্রাপ্ত, তবে দুটি আলাদা টেবিল থাকবে, একটিতে Employee এবং আরেকটিতে Manager এর ডেটা সংরক্ষিত হবে।
2. NHibernate Mapping
Table Per Concrete Class কৌশলটি ব্যবহার করতে, আপনাকে প্রতিটি কনক্রিট ক্লাসের জন্য আলাদা আলাদা টেবিল এবং ম্যাপিং কনফিগারেশন তৈরি করতে হবে।
Employee Class Mapping:
public class EmployeeMap : ClassMap<Employee>
{
public EmployeeMap()
{
Table("Employees"); // Employee টেবিল
Id(x => x.Id);
Map(x => x.Name);
Map(x => x.Salary);
}
}
Manager Class Mapping:
public class ManagerMap : ClassMap<Manager>
{
public ManagerMap()
{
Table("Managers"); // Manager টেবিল
Id(x => x.Id);
Map(x => x.Name);
Map(x => x.Salary);
Map(x => x.Department); // Manager এর Department
}
}
এখানে, EmployeeMap এবং ManagerMap ক্লাসগুলো আলাদা টেবিল ম্যাপিং কনফিগারেশন করে, এবং Employee এবং Manager এর জন্য আলাদা টেবিল তৈরি করে।
3. Database Structure
উপরের ম্যাপিং কনফিগারেশনের ভিত্তিতে, আপনি দুটি আলাদা টেবিল পাবেন:
Employees Table:
| Id | Name | Salary |
|---|---|---|
| 1 | John Doe | 50000 |
| 2 | Jane Smith | 60000 |
Managers Table:
| Id | Name | Salary | Department |
|---|---|---|---|
| 1 | Sarah Lee | 80000 | HR |
4. Querying Data
যেহেতু এই কৌশলে Employee এবং Manager এর জন্য আলাদা টেবিল রয়েছে, আপনি পৃথকভাবে তাদের সারণী থেকে ডেটা রিট্রাইভ করতে পারবেন। উদাহরণস্বরূপ, Employee টেবিল থেকে সমস্ত Employee তথ্য পাওয়া যাবে, এবং Manager টেবিল থেকে শুধুমাত্র Manager তথ্য পাওয়া যাবে।
using (var session = NHibernateHelper.SessionFactory.OpenSession())
{
// All Employees
var employees = session.Query<Employee>().ToList();
// All Managers
var managers = session.Query<Manager>().ToList();
}
এখানে, employees এবং managers দুটি আলাদা তালিকা হিসেবে ডেটা রিট্রাইভ করবে, কারণ তারা আলাদা টেবিল থেকে আসছে।
5. Table Per Concrete Class এর সুবিধা
- ডেটাবেস পারফরম্যান্স: এই কৌশলটি পারফরম্যান্সের দৃষ্টিকোণ থেকে উপকারী হতে পারে, কারণ এটি শুধুমাত্র একক কনক্রিট ক্লাসের জন্য ডেটা ধারণ করে, এবং অন্যান্য শ্রেণীগুলোর জন্য একত্রিত টেবিলের তুলনায় ডেটাবেসের অ্যাক্সেস দ্রুত হতে পারে।
- টেবিলের সরলতা: যদি আপনি বিভিন্ন কনক্রিট ক্লাসের জন্য আলাদা আলাদা ডেটা সংরক্ষণ করতে চান এবং তাদের মধ্যে উত্তরাধিকারী সম্পর্ক না রেখে একে অপরকে স্বাধীনভাবে সংরক্ষণ করতে চান, তাহলে এটি একটি ভালো পছন্দ হতে পারে।
6. Table Per Concrete Class এর সীমাবদ্ধতা
- ডুপ্লিকেট কলাম: প্রতি কনক্রিট ক্লাসের জন্য আলাদা টেবিল থাকলে, আপনি যদি একই বৈশিষ্ট্য (যেমন Salary) দুটি ক্লাসে ব্যবহার করেন, তবে ডুপ্লিকেট কলাম তৈরি হতে পারে।
- ডেটার পুনঃব্যবহার: উত্তরাধিকারী শ্রেণীগুলোর মধ্যে ডেটা পুনঃব্যবহার করতে না পারার কারণে কোড পুনঃব্যবহারের সুবিধা কমে যেতে পারে।
- ডেটা ব্যবস্থাপনা: একাধিক টেবিল ব্যবস্থাপনা কিছু ক্ষেত্রে জটিল হতে পারে, বিশেষ করে যখন সম্পর্কিত ক্লাসগুলোর মধ্যে তথ্যের সমন্বয় প্রয়োজন।
Table Per Concrete Class (TPC) কৌশলটি কিছু বিশেষ ক্ষেত্রে কার্যকর হতে পারে, তবে এটি সর্বদা সর্বোত্তম পছন্দ নয়। আপনার প্রয়োজনের ভিত্তিতে সঠিক ইনহেরিটেন্স কৌশল নির্বাচন করা উচিত।
Read more